package com.david.webtest.hybrid;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.david.webtest.R;

import androidx.annotation.Nullable;

/***
 * html 向native传递数据
 * 1：自定义scheme方式，在app端对应的方法拦截url判断是否应该处理；
 * 2：通过html调用alert、confirm、prompt方法，native拦截方法并重写逻辑
 * 3：通过定义jsBrige方式（android），JS注入对象（iOS），html调用相关方法
 *
 * native向html传递数据：
 * 1: android通过evaluateJavascript，ios通过stringByEvaluatingJavaScriptFromString调用js方法及获取返回值
 * 2：html中定义js方法，native通过注入js调用方法传递：
 *
 *
 * mTopWebView.evaluateJavascript("javascript:nativeCallJs(\"lala\")", new ValueCallback<String>() {
 *             @Override
 *             public void onReceiveValue(String value) {
 *                 Log.e("hybrid", "js return:"+value);
 *             }
 *         });
 * TODO 添加下拉刷新逻辑
 */
public class HybridActivity extends Activity {
    private ViewGroup root;

    private WebView[] pages = new WebView[10];//最多显示10级页面
    private WebView[] tabPages = null;//tab页面
    private int pageSize = 0;
    private WebView mTopWebView;
    private boolean firstIn = true;

    private FrameLayout.LayoutParams normalParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hybrid);
        root = findViewById(R.id.root);
        mTopWebView = createWebPage();

        normalParams.topMargin = dp2px(50);
        root.addView(mTopWebView, normalParams);

        mTopWebView.loadUrl("file:///android_asset/hybridtest.html");

        pages[0]=mTopWebView;
        ++pageSize;
    }

    /**
     * 调用app方法使用app功能：
     * 1.网络:(wifi://list)
     *      打开／关闭
     *      获取打开／关闭状态
     *      获取wifi列表
     *      连接wifi
     *      获取信号强度
     * 2.设备信息：
     *      获取分辨率
     *      获取像素密度
     *      电池电量
     *      横竖屏
     *      屏幕亮度
     *      声音大小
     * 3.文件：
     *      获取文件列表
     *      选择文件／图片
     *      保存文件／图片
     *      上传文件／图片
     * 4.蓝牙
     *      打开／关闭蓝牙
     *      获取打开／关闭状态
     *      获取蓝牙列表
     *      连接蓝牙
     *      获取信号强度
     * 5.缓存键值对
     * 6.播放音乐视频
     * 其他可参考：https://developers.weixin.qq.com/miniprogram/dev/api/
     *
     * */
    private void callAppFuncs(){

    }

    private WebView createWebPage(){
        WebView webView = new WebView(this);

        WebSettings webSettings = webView.getSettings();
        webSettings.setJavaScriptEnabled(true);

        webView.setWebChromeClient(webChromeClient);
        webView.setWebViewClient(webViewClient);

        return webView;
    }

    private final WebChromeClient webChromeClient = new WebChromeClient(){
        @Override
        public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
            Log.e("hybrid","onJsAlert..." + url + " " + message);
            result.confirm();
            super.onJsAlert(view, url, message, result);
            return true;
        }

        @Override
        public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
            Log.e("hybrid","onJsConfirm..." + url + " " + message);
            result.confirm();
            super.onJsConfirm(view, url, message, result);
            return true;
        }

        /**
         * page://
         *      nav:跳转页面，nav：../page1.html?
         *      redirect:
         *      back:
         * device://
         *
         * */
        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
            Log.e("hybrid","onJsPrompt..." + url + " " + message);
            super.onJsPrompt(view, url, message, defaultValue, result);
            try {

                Uri uri =  Uri.parse(message);

                if (message.startsWith("page://")){
                        String redirectUrl = uri.getQueryParameter("url");

                        if ("nav".equals(uri.getHost())) {

                            root.removeView(mTopWebView);
                            if (pageSize ==  0) {
                                tabParent.setVisibility(View.GONE);
                            }
                            mTopWebView = createWebPage();
                            root.addView(mTopWebView, normalParams);

                            pages[pageSize] = mTopWebView;


                            ++pageSize;
                            String navUrl = Uri.parse(message).getQueryParameter("url");
                            mTopWebView.loadUrl(navUrl);
                            // TODO: 2021/8/27 判断是否有底部tab，有tab时添加到childCount-1位置

                        } else if ("back".equals(uri.getHost())) {
                            navBack();
                            return true;
                        } else if ("redirect".equals(uri.getHost())) {
                            mTopWebView.loadUrl(redirectUrl);
                        }


                    result.confirm("success");

                } else if (message.startsWith("device://")) {
                    StringBuilder builder = new StringBuilder();
                    DisplayMetrics metrics = getResources().getDisplayMetrics();

                    builder.append("{")
                            .append("\"widthPixels\":\"").append(metrics.widthPixels).append("\"")
                            .append(",\"heightPixels\":\"").append(metrics.heightPixels).append("\"")
                            .append(",\"density\":\"").append(metrics.density).append("\"")
                            .append(",\"rpx2Px\":\"").append(metrics.widthPixels / 750).append("\"")//计算1rpx为多少px，默认设备横向都为750rpx
                            .append(",\"os\":\"Android\"")
                            .append("}");
                    result.confirm(builder.toString());

                } else if (message.startsWith("wifi://")){

                } else if (message.startsWith("bluetooth://")) {

                } else if (message.startsWith("file://")) {

                } else if (message.startsWith("tab://")) {

                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return true;
//                return super.onJsPrompt(view, url, message, defaultValue, result);
        }
    };

    private final WebViewClient webViewClient = new WebViewClient() {
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView webView, WebResourceRequest request) {
            String url = request.getUrl().toString();
            if (url.endsWith(".png") || url.endsWith(".jpg") || url.endsWith(".webp") || url.endsWith(".NEF")) {
            }
            return super.shouldInterceptRequest(webView, request);
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if (firstIn) {
                addTab();
                firstIn = false;
            }
        }
    };

    @Override
    public void onBackPressed() {
//        super.onBackPressed();
        navBack();
    }

    private void navBack(){
        root.removeView(mTopWebView);
        mTopWebView.destroy();

        if ((pageSize == 0 && tabPages != null) || (pageSize == 1 && tabPages == null)) {
            if (tabPages != null) {
                for (int i = 0; i < tabPages.length; i++) {
                    if (tabPages[i] != null)
                        tabPages[i].destroy();
                }
            }
            finish();
            return;
        }
        if (pageSize > 1) {
            pages[pageSize - 1] = null;
            --pageSize;
            mTopWebView = pages[pageSize - 1];

            root.addView(mTopWebView, normalParams);
        } else {
            tabParent.setVisibility(View.VISIBLE);

            mTopWebView = tabPages[currentTab];
            root.addView(mTopWebView);
            pageSize=0;
        }

    }

    /**
     * dp转px
     *
     * @param dp
     * @return
     */
    private int dp2px(float dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics());
    }

    /**从第一个html页面获取tabs信息*/
    private void addTab(){
        mTopWebView.evaluateJavascript("javascript:getTabs(\"{\\\"os\\\":\\\"Android\\\"}\")", new ValueCallback<String>() {
              @Override
              public void onReceiveValue(String value) {
                  JSONObject jsonObject = JSON.parseObject((String) JSON.parse(value));
                  if (jsonObject.getIntValue("size") > 1) {
                      int size = jsonObject.getIntValue("size");

                      tabData = jsonObject.getJSONArray("tabs");

                      tabPages = new WebView[size];
                      FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp2px(50));
                      params.gravity = Gravity.BOTTOM;
                      int width = getResources().getDisplayMetrics().widthPixels / 5;
                      tabParent = new FrameLayout(HybridActivity.this);
                      root.addView(tabParent, params);
                      for (int i = 0; i < size; i++) {
                          ViewGroup tab = (ViewGroup) LayoutInflater.from(HybridActivity.this).inflate(R.layout.item_bottom_tab, tabParent, false);
                          FrameLayout.LayoutParams tabParam = new FrameLayout.LayoutParams(width, ViewGroup.LayoutParams.MATCH_PARENT);
                          tabParam.leftMargin = i * width;
                          tabParent.addView(tab, tabParam);

                          tab.setOnClickListener(onTabClickListener);
                          tab.setTag(i);
                      }

                      tabPages[0] = mTopWebView;
                      pageSize = 0;
                      FrameLayout.LayoutParams tabParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                      tabParams.topMargin = dp2px(50);
                      tabParams.bottomMargin = dp2px(50);
                      mTopWebView.setLayoutParams(tabParams);
                      pages[0] = null;
                  }
              }
          });
    }

    private int currentTab = 0;
    private FrameLayout tabParent = null;

    private JSONArray tabData;

    private View.OnClickListener onTabClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (v.getTag() != null) {
                int index = ((int) v.getTag());
                currentTab = index;

                if (tabPages[index] == null) {
                    tabPages[index] = createWebPage();
                    tabPages[index].loadUrl("file:///android_asset/" + tabData.getJSONObject(index).getString("page"));
                    FrameLayout.LayoutParams tabParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
                    tabParams.topMargin = dp2px(50);
                    tabParams.bottomMargin = dp2px(50);
                    tabPages[index].setLayoutParams(tabParams);
                }
                root.removeView(mTopWebView);
                mTopWebView = tabPages[index];

                root.addView(mTopWebView);
            }
        }
    };
}
